'use client';
import WebrtcNav from '@/components/WebrtcNav';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { io, Socket } from 'socket.io-client';
let socket: Socket;
let roomId = 'room-2';
let selfId = crypto.randomUUID();
type PeerConnectionInfo = {
	pc: RTCPeerConnection;
	role: 'caller' | 'callee';
	channel: RTCDataChannel;
};
type Msg = {
	role: 'send' | 'receive';
	content: string;
};

let pcMap = new Map<string, PeerConnectionInfo>();
function log(...args: any[]) {
	console.log(`[${new Date().toLocaleTimeString()}]`, ...args);
}
function createPeerConnection(remoteUserId: string): {
	pc: RTCPeerConnection;
	channel: RTCDataChannel;
} {
	const pc = new RTCPeerConnection({
		iceServers: [
			{
				urls: 'stun:124.221.59.25:3478',
				username: 'test',
				credential: '123456',
			},
			{
				urls: 'turn:124.221.59.25:3478',
				username: 'test',
				credential: '123456',
			},
		],

		//@ts-ignore
		// continualGatheringPolicy: 'gather_continually',
	});
	const datachannel = pc.createDataChannel('chat', {
		ordered: true,
	});
	datachannel.onopen = () => log('✅ DataChannel 已打开');
	datachannel.onclose = () => log('❌ DataChannel 已关闭');

	// 远端监听 DataChannel
	// remotePC.current.ondatachannel = (event) => {
	// 	receiveChannel.current = event.channel;
	// 	receiveChannel.current.onmessage = (e) => log(`📩 收到: ${e.data}`);
	// 	receiveChannel.current.onopen = () => log('📡 远端 DataChannel 已打开');
	// };

	// 发送 ICE 候选信息到对方
	pc.onicecandidate = (event) => {
		if (event.candidate) {
			console.log('发送 ICE 候选信息:', event.candidate);
			socket.emit('candidate', {
				roomId,
				from: selfId,
				to: remoteUserId,
				candidate: event.candidate,
			});
		}
		if (event.candidate === null) {
			console.log('✅ 所有 ICE 候选收集完毕');
		}
	};

	// 接收远端媒体流并绑定到 video 元素
	// pc.ontrack = (event) => {
	// 	console.log('接收到媒体流:', event.streams);
	// 	const remoteVideo = document.getElementById(
	// 		'remote-video',
	// 	) as HTMLVideoElement;
	// 	const remoteStream = event.streams[0];
	// 	console.log('✅ 接收到远端媒体流:', remoteStream);
	// 	console.log('🎥 视频轨道:', remoteStream.getVideoTracks());
	// 	console.log('🎤 音频轨道:', remoteStream.getAudioTracks());

	// 	remoteVideo.srcObject = remoteStream;
	// };

	// 添加本地媒体流轨道
	// if (localStream) {
	// 	console.log('创建 RTCPeerConnection 实例:', localStream?.getTracks());
	// 	localStream.getTracks().forEach((track) => {
	// 		pc.addTrack(track, localStream!); // or just `localStream` since we already checked
	// 	});
	// } else {
	// 	console.warn('Local stream is not available.');
	// }

	return { pc, channel: datachannel };
}

const Txt2Txt: React.FC = () => {
	const [messages, setMessages] = useState<Msg[]>([]);
	const [input, setInput] = useState('');
	const [peers, setPeers] = useState<{ userId: string; role: string }[]>([]);
	const [index, setIndex] = useState(0);
	const [connnected, setConnected] = useState('');
	const [stats, setStats] = useState<any[]>([]);
	// const localPC = useRef<RTCPeerConnection | null>(null);
	const remotePC = useRef<RTCPeerConnection | null>(null);
	const sendChannel = useRef<RTCDataChannel | null>(null);
	const receiveChannel = useRef<RTCDataChannel | null>(null);
	const timer = useRef<any>(null);

	const handleConnection = async () => {
		if (peers.length > 0) {
			console.log('Connecting to:', peers[0].userId);
			const remoteUserId = peers[0].userId;
			const { pc, channel } = createPeerConnection(remoteUserId);
			const offer = await pc.createOffer({ iceRestart: true });
			sendChannel.current = channel;
			console.log('Created offer:', offer);

			await pc.setLocalDescription(offer);

			// 向服务器发送 Offer 消息
			socket.emit('offer', {
				roomId,
				from: selfId,
				to: remoteUserId,
				sdp: offer,
			});
			pcMap.set(peers[0].userId, { pc, channel, role: 'caller' });

			pc.oniceconnectionstatechange = () => {
				console.log('oniceconnectionstatechange:', pc.iceConnectionState);
				setConnected(pc.iceConnectionState);
			};
			if (timer.current) {
				clearInterval(timer.current);
				timer.current = null;
			}

			timer.current = setInterval(async () => {
				const status = await pc.getStats();
				const arr: any[] = [];
				status.forEach((stat) => arr.push(stat));

				// console.log('getStats:',status);
				setStats(arr);
			}, 5000);
			pc.ondatachannel = (event) => {
				console.log('收到数据通道:', event.channel);
				console.log('数据通道:', event);
				// receiveChannel.current = event.channel;
				channel.onmessage = (e) => {
					setMessages((prev) => [
						...prev,
						{
							role: 'receive',
							content: e.data,
						},
					]);
					console.log(`📩 收到: ${e.data}`);
				};
				channel.onopen = () => console.log('✅ DataChannel 已打开----remote');
				// receiveChannel.current.onopen = () => log('📡 远端 DataChannel 已打开');
			};
			// channel.onmessage = (e) => log(`📩 收到: ${e.data}`);
			// pc.ondatachannel = (event) => {
			// 	receiveChannel.current = event.channel;
			// };
		}
	};
	useEffect(() => {
		// 初始化 Socket 连接
		socket = io('https://lizhan.fun', { path: '/perf/v1/socket.io' });

		socket.on('connect', () => {
			console.log('已连接到信令服务器');
			socket.emit('join', {
				roomId,
				userId: selfId,
				role: 'audience',
				mode: 'p2p',
			});
		});

		// 收到房间信息：当前已加入的用户列表
		socket.on('joined', ({ roomId: r, selfId: me, peers: peerList }) => {
			console.log('加入房间:', r, '用户ID:', me, '成员:', peerList);
			setPeers(peerList);
		});

		// 收到对方发来的 Offer 请求
		socket.on('offer', async ({ from, sdp }) => {
			console.log('收到 Offer:', from, sdp);
			const { pc, channel } = createPeerConnection(from);
			pcMap.set(from, { pc, channel, role: 'callee' });
			pc.ondatachannel = (event) => {
				console.log('收到数据通道:', event.channel);
				console.log('数据通道:', event);
				receiveChannel.current = event.channel;
				receiveChannel.current.onmessage = (e) => {
					setMessages((prev) => [
						...prev,
						{
							role: 'receive',
							content: e.data,
						},
					]);
					// console.log(`📩 收到: ${e.data}`);
				};
				receiveChannel.current.onopen = () =>
					console.log('✅ DataChannel 已打开----remote DataChannel 已打开');
				// receiveChannel.current.onopen = () => log('📡 远端 DataChannel 已打开');
			};
			pc.oniceconnectionstatechange = () => {
				console.log('oniceconnectionstatechange:', pc.iceConnectionState);
				setConnected(pc.iceConnectionState);
			};
			if (timer.current) {
				clearInterval(timer.current);
				timer.current = null;
			}

			timer.current = setInterval(async () => {
				const status = await pc.getStats();
				const arr: any[] = [];
				status.forEach((stat) => arr.push(stat));

				// console.log('getStats:',status);
				setStats(arr);
			}, 5000);

			await pc.setRemoteDescription(new RTCSessionDescription(sdp));
			const answer = await pc.createAnswer();
			await pc.setLocalDescription(answer);

			socket.emit('answer', {
				roomId,
				from: selfId,
				to: from,
				sdp: answer,
			});

			// setPcMap((prev) => {
			// 	const map = new Map(prev);
			// 	map.set(from, { pc, role: 'callee' });
			// 	return map;
			// });
		});

		// 收到 Answer 响应
		socket.on('answer', async ({ from, sdp }) => {
			const pcInfo = pcMap.get(from);
			if (pcInfo && !pcInfo.pc.currentRemoteDescription) {
				await pcInfo.pc.setRemoteDescription(new RTCSessionDescription(sdp));
				console.log(`已设置来自 ${from} 的 Answer`);
			}
		});

		// 收到 ICE 候选信息
		socket.on('candidate', async ({ from, candidate }) => {
			const pcInfo = pcMap.get(from);
			if (pcInfo && candidate) {
				try {
					await pcInfo.pc.addIceCandidate(new RTCIceCandidate(candidate));
				} catch (err) {
					console.error(`添加 ICE 候选失败:`, err);
				}
			}
		});
		socket.on('user-left', ({ roomId, userId }) => {
			console.log(`${userId} 离开了房间 ${roomId}`);

			// 更新用户列表：从前端状态中删除该用户
			setPeers((prev) => prev.filter((peer) => peer.userId !== userId));
		});

		// 清理资源
		return () => {
			socket.disconnect();
			pcMap.forEach((pcInfo) => pcInfo.pc.close());
			// setPcMap(new Map());
		};
	}, []);

	const curcandiate = useMemo(() => {
		const pair = stats.find(
			(item) => item.type === 'candidate-pair' && item.nominated,
		);
		if (pair) {
			return stats.find(
				(item) =>
					item.type === 'local-candidate' && item.id === pair.localCandidateId,
			);
		}
		return null;
	}, [stats]);

	// useEffect(() => {
	// 	// 初始化 PeerConnection
	// 	localPC.current = new RTCPeerConnection();
	// 	remotePC.current = new RTCPeerConnection();

	// 	// 本地创建 DataChannel
	// 	sendChannel.current = localPC.current.createDataChannel('chat', {
	// 		ordered: true,
	// 	});
	// 	sendChannel.current.onopen = () => log('✅ DataChannel 已打开');
	// 	sendChannel.current.onclose = () => log('❌ DataChannel 已关闭');

	// 	// 远端监听 DataChannel
	// 	remotePC.current.ondatachannel = (event) => {
	// 		receiveChannel.current = event.channel;
	// 		receiveChannel.current.onmessage = (e) => log(`📩 收到: ${e.data}`);
	// 		receiveChannel.current.onopen = () => log('📡 远端 DataChannel 已打开');
	// 	};

	// 	// ICE 候选交换
	// 	localPC.current.onicecandidate = (e) => {
	// 		if (e.candidate) remotePC.current?.addIceCandidate(e.candidate);
	// 	};
	// 	remotePC.current.onicecandidate = (e) => {
	// 		if (e.candidate) localPC.current?.addIceCandidate(e.candidate);
	// 	};

	// 	// SDP Offer/Answer 交换
	// 	(async () => {
	// 		if (!localPC.current || !remotePC.current) return;

	// 		const offer = await localPC.current.createOffer();
	// 		await localPC.current.setLocalDescription(offer);
	// 		await remotePC.current.setRemoteDescription(offer);

	// 		const answer = await remotePC.current.createAnswer();
	// 		await remotePC.current.setLocalDescription(answer);
	// 		await localPC.current.setRemoteDescription(answer);
	// 	})();

	// 	return () => {
	// 		sendChannel.current?.close();
	// 		receiveChannel.current?.close();
	// 		localPC.current?.close();
	// 		remotePC.current?.close();
	// 	};
	// }, []);

	// const log = (msg: Msg) => {
	// 	setMessages((prev) => [...prev, msg]);
	// };

	const sendMessage = () => {
		if (sendChannel.current) {
			sendChannel.current.send(input);
			setMessages((prev) => [...prev, { role: 'send', content: input }]);
		} else if (receiveChannel.current) {
			receiveChannel.current.send(input);
			setMessages((prev) => [...prev, { role: 'send', content: input }]);
		} else {
			console.log('⚠️ DataChannel 未打开');
		}
		setInput('');
	};

	return (
		<div className="mt-2">
			<WebrtcNav text="文本通话"></WebrtcNav>
			<div className="mt-2 flex flex-wrap gap-6 shadow-sm p-2 items-center">
				<button
					type="button"
					className="px-4 py-2 text-white bg-blue-500 rounded-md hover:bg-blue-600"
					onClick={handleConnection}
				>
					connect
				</button>
				<span className="text-sm bg-gray-100 rounded-sm p-2">{connnected}</span>
				<span className="text-sm bg-gray-100 rounded-sm p-2">
					{curcandiate
						? curcandiate.networkType + '-' + curcandiate.candidateType
						: '--'}
				</span>
			</div>
			<div className="flex">
				<div className="mt-2 flex-1 p-2 shadow-lg h-[500px]">
					<div className="flex">
						<textarea
							className="flex-1 px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
							placeholder="输入消息..."
							value={input}
							onChange={(e) => setInput(e.target.value)}
							rows={3}
						/>
						<button
							className="px-4 py-2 ml-2 text-white bg-blue-500 rounded-md hover:bg-blue-600"
							onClick={sendMessage}
						>
							发送
						</button>
					</div>
					<div className="mt-2">
						<h3>日志</h3>
						<div style={{ whiteSpace: 'pre-line' }}>
							{messages.map((m, i) => (
								<div key={i}>
									{m.role}-{m.content}
								</div>
							))}
						</div>
					</div>
					<div className="group relative inline-block">
						<button className="px-4 py-2 bg-blue-500 text-white">悬停我</button>
						<div className="absolute mt-2 hidden group-hover:block bg-white border rounded shadow">
							<p className="p-2">悬停时显示的内容</p>
						</div>
					</div>
					{/* <ul>
				{stats.map((statsItem) => {
					return <li key={statsItem.id}>{JSON.stringify(statsItem)},</li>;
				})}
			</ul> */}
				</div>

				<div className="mt-2 w-100 px-4 shadow-lg">
					<ul className="flex flex-wrap">
						{peers.map((peer, i) => (
							<li
								key={peer.userId}
								className={
									'p-2 cursor-pointer ' +
									(index == i
										? 'w-100 bg-gray-500 text-white'
										: 'w-100 bg-gray-200 text-black')
								}
							>
								{peer.userId}
							</li>
						))}
					</ul>
				</div>
			</div>
		</div>
	);
};

export default Txt2Txt;
